package icestorm;
import com.guo.util.ResourceUtil;
import icestorm.adaptor.HelloSubscriberAdaptor;

/**
 * ICE 订阅topic接口
 *
 * @author keriezhang
 * @date 2016/10/31
 */
public class Subscriber extends com.zeroc.Ice.Application {


    /***
     * 订阅ICE接口
     * @param args
     * @return
     */
    @Override
    public int run(String[] args) {
        args = communicator().getProperties().parseCommandLineOptions("Clock", args);
        // topic Name
        String topicName = "helloService";
        String option = "None";
        boolean batch = false;
        String id = null;
        String retryCount = null;
        int i;
        for (i = 0; i < args.length; ++i) {
            String oldoption = option;
            if ("--datagram".equals(args[i])) {
                option = "Datagram";
            } else if ("--twoway".equals(args[i])) {
                option = "Twoway";
            } else if ("--ordered".equals(args[i])) {
                option = "Ordered";
            } else if ("--oneway".equals(args[i])) {
                option = "Oneway";
            } else if ("--batch".equals(args[i])) {
                batch = true;
            } else if ("--id".equals(args[i])) {
                ++i;
                if (i >= args.length) {
                    usage();
                    return 1;
                }
                id = args[i];
            } else if ("--retryCount".equals(args[i])) {
                ++i;
                if (i >= args.length) {
                    usage();
                    return 1;
                }
                retryCount = args[i];
            } else if (args[i].startsWith("--")) {
                usage();
                return 1;
            } else {
                topicName = args[i++];
                break;
            }

            if (!oldoption.equals(option) && !"None".equals(oldoption)) {
                usage();
                return 1;
            }
        }

        if (i != args.length) {
            usage();
            return 1;
        }

        if (retryCount != null) {
            if ("None".equals(option)) {
                option = "Twoway";
            } else if (!"Twoway".equals(option) && !"Ordered".equals(option)) {
                usage();
                return 1;
            }
        }

        if (batch && ("Twoway".equals(option) || "Ordered".equals(option))) {
            System.err.println(appName() + ": batch can only be set with oneway or datagram");
            return 1;
        }

        com.zeroc.IceStorm.TopicManagerPrx manager = com.zeroc.IceStorm.TopicManagerPrx.checkedCast(communicator().propertyToProxy("TopicManager.Proxy"));
        if (manager == null) {
            System.err.println("invalid proxy");
            return 1;
        }
        // Retrieve the topic.
        com.zeroc.IceStorm.TopicPrx topic;
        try {
            topic = manager.retrieve("helloService");
        } catch (com.zeroc.IceStorm.NoSuchTopic e) {
            try {
                topic = manager.create("helloService");
            } catch (com.zeroc.IceStorm.TopicExists ex) {
                System.err.println(appName() + ": temporary failure, try again.");
                return 1;
            }
        }
        // 创建Adapter
        com.zeroc.Ice.ObjectAdapter adapter = communicator().createObjectAdapter("Subscriber");
        //
        // Add a servant for the Ice object. If --id is used the
        // identity comes from the command line, otherwise a UUID is
        // used.
        //
        // id is not directly altered since it is used below to detect
        // whether subscribeAndGetPublisher can raise
        // AlreadySubscribed.
        //
        com.zeroc.Ice.Identity subId = new com.zeroc.Ice.Identity(id, "");
        if (subId.name == null) {
            subId.name = java.util.UUID.randomUUID().toString();
        }
        com.zeroc.Ice.ObjectPrx subscriber = adapter.add(new HelloSubscriberAdaptor(), subId);
        //
        // Activate the object adapter before subscribing.
        //
        adapter.activate();
        // topic质量参数
        java.util.Map<String, String> qos = new java.util.HashMap<>();
        if (retryCount != null) {
            qos.put("retryCount", retryCount);
        }
        //
        // Set up the proxy.
        //
        if ("Datagram".equals(option)) {
            if (batch) {
                subscriber = subscriber.ice_batchDatagram();
            } else {
                subscriber = subscriber.ice_datagram();
            }
        } else if ("Twoway".equals(option)) {
            // Do nothing to the subscriber proxy. Its already twoway.
        } else if ("Ordered".equals(option)) {
            // Do nothing to the subscriber proxy. Its already twoway.
            qos.put("reliability", "ordered");
        } else if ("Oneway".equals(option) || "None".equals(option)) {
            if (batch) {
                subscriber = subscriber.ice_batchOneway();
            } else {
                subscriber = subscriber.ice_oneway();
            }
        }
        // 订阅
        try {
            topic.subscribeAndGetPublisher(qos, subscriber);
        } catch (com.zeroc.IceStorm.AlreadySubscribed e) {
            // If we're manually setting the subscriber id ignore.
            if (id == null) {
                e.printStackTrace();
                return 1;
            } else {
                System.out.println("reactivating persistent subscriber");
            }
        } catch (com.zeroc.IceStorm.InvalidSubscriber e) {
            e.printStackTrace();
            return 1;
        } catch (com.zeroc.IceStorm.BadQoS e) {
            e.printStackTrace();
            return 1;
        }

        shutdownOnInterrupt();
        communicator().waitForShutdown();

        topic.unsubscribe(subscriber);

        return 0;
    }
    private void usage() {
        System.out.println("Usage: " + appName() + " [--batch] [--datagram|--twoway|--ordered|--oneway] " + "[--retryCount count] [--id id] [topic]");
    }
    public static void main(String[] args) {
        String subConfigPath = ResourceUtil.getResourcePath("/iceStorm/config.sub");
        Subscriber app = new Subscriber();
        int status = app.main("Subscriber", args, subConfigPath);
        System.exit(status);
    }
}
